package com.getaway.getaway.route;

import com.getaway.getaway.model.GatewayFilterDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
	@Autowired
	private RouteDefinitionWriter routeDefinitionWriter;
	@Autowired
	private RouteDefinitionLocator routeDefinitionLocator;

	/**
	 * 发布事件
	 */
	@Autowired
	private ApplicationEventPublisher publisher;

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		this.publisher = applicationEventPublisher;
	}

	/**
	 * 删除路由
	 * @param id
	 * @return
	 */
	public String delete(String id) {
		try {
			this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
			this.publisher.publishEvent(new RefreshRoutesEvent(this));
			return "delete success";
		} catch (Exception e) {
			return "delete fail";
		}
	}

	/**
	 * 更新路由
	 * @param definitions
	 * @return
	 */
	public String updateList(List<RouteDefinition> definitions) {
		// 删除缓存routerDefinition
		List<RouteDefinition> routeDefinitionsExits =  routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
		if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
			routeDefinitionsExits.forEach(routeDefinition -> {
				delete(routeDefinition.getId());
			});
		}
		definitions.forEach(definition -> {
			updateById(definition);
		});
		return "success";
	}

	/**
	 * 更新路由
	 * @param definition
	 * @return
	 */
	public String updateById(RouteDefinition definition) {
		try {
			this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
		} catch (Exception e) {
			return "update fail,not find route  routeId: "+definition.getId();
		}
		try {
			routeDefinitionWriter.save(Mono.just(definition)).subscribe();
			this.publisher.publishEvent(new RefreshRoutesEvent(this));
			return "success";
		} catch (Exception e) {
			return "update route fail";
		}
	}

	/**
	 * 增加路由
	 * @param definition
	 * @return
	 */
	public String add(RouteDefinition definition) {

		routeDefinitionWriter.save(Mono.just(definition)).subscribe();
		this.publisher.publishEvent(new RefreshRoutesEvent(this));
		return "success";
	}
}
